package com.gitee.loyo;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.gitee.loyo.utils.CryptoUtils;
import com.gitee.loyo.utils.Factory;
import com.gitee.loyo.utils.SeqHelper;
import com.google.common.hash.Hashing;
import lombok.Data;
import lombok.SneakyThrows;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;

import static java.nio.charset.StandardCharsets.UTF_8;

@Data
public class Result<T> implements Serializable {
    @JsonProperty("Ret")
    private Integer ret;
    @JsonProperty("Msg")
    private String msg;
    @JsonProperty("Data")
    private T data;
    @JsonProperty("Sig")
    private String sig;
    @JsonIgnore
    private String timestamp;
    @JsonIgnore
    private String seq;

    public Result() {
    }

    public Result(Request request) {
        this.timestamp = request.getTimestamp();
        this.seq = request.getSeq();
    }

    public Result(Result result, T data) {
        this.ret = result.getRet();
        this.msg = result.getMsg();
        this.data = data;
        this.sig = result.getSig();
    }

    @SneakyThrows
    public Result<String> encryptAndSign(String operatorId, String dataSecretIV, String dataSecret, String sigSecret, Factory<T, String> factory){
        Result<String> newResult = new Result<>();
        newResult.data = CryptoUtils.encodeByAes128_CBC_PKCS5Padding(factory.create(this.data), dataSecretIV, dataSecret);

        String content = operatorId + newResult.data + timestamp + seq;
        newResult.sig = Hashing.hmacMd5(sigSecret.getBytes(UTF_8)).hashString(content, UTF_8).toString().toUpperCase();
        newResult.ret = this.ret;
        newResult.msg = this.msg;
        return newResult;
    }
}
